#include "Core.h"


__BEGIN_NAMESPACE


int                  sTagStackIndex = 0;
int                  sMemoryTagStack[MAX_MTAG_STACK] = {0};
size_t               sMemoryStatistic[MAX_TAGS] = {0};
const char*          sAllocMemoryFile = "";
INT                  sAllocMemoryLine = -1;
struct MemAllocInfo* pMemAllocHead = NULL;

void PushMallocTag( int tag )
{
	sMemoryTagStack[sTagStackIndex++] = tag;
}

void PopMallocTag( )
{
	--sTagStackIndex;
}

void MallocInfo( const char* file, const unsigned int line )
{
	Assert(strlen(file)<MAX_MEMORY_FILE_SIZE-1);
	sAllocMemoryFile = file;
	sAllocMemoryLine = line;
}

size_t GetMemoryUsage( int tag )
{
	return sMemoryStatistic[tag];
}

void MemoryDump()
{
	UINT32 MemTotalSize = 0;
	INT MemTotalChunk = 0;
	struct MemAllocInfo* pAllocInfo = pMemAllocHead;
	Trace( "\nDump memory information:\n" );
	while( pAllocInfo )	{
		//Trace( "    %d Bytes @ %s(%d) \n", pAllocInfo->Size, pAllocInfo->Filename, pAllocInfo->FileLine );
		MemTotalSize += pAllocInfo->Size;
		++MemTotalChunk;
		pAllocInfo = pAllocInfo->pNext;
	}
	Trace( "Total: %i Chunks(%i Bytes) are still allocated.\n", MemTotalChunk , MemTotalSize );
}


static int g_LastError = E_Ok;

const char* GetErrDescription( int err ) {

	static const char* s_ErrorDescription[] = {
	"Everything worked fine",                                        //E_Ok
	"Bad parameter passed to the function",                          //E_BadParameter
	"Value/Parameter out of range",                                  //E_OutOfRange
	"Overflow occurred (typically buffer)",                          //E_Overflow
	"Unsupported feature/function",                                  //E_Unsupported
	"The resource/object requested can't be found",                  //E_NotFound
	"The device requested can't be found",                           //E_DeviceNotFound
	"The resource is already in use",                                //E_AlreadyInUse
	"The file requested can't be found",                             //E_FileNotFound
	"The file's path requested can't be found",                      //E_PathNotFound
	"The resource/object you're registering is conflicting another", //E_Conflict
	"A low level error occurred (hardware or OS)",                   //E_LowLevelError
	"Data feeding has been corrupted",                               //E_Corrupted
	"The operation requested is currently processing",               //E_Processing
	"The file already exists",                                       //E_AlreadyExist
	"Access to the resource is denied",                              //E_AccessDenied
	"The device is full, no more appending is possible",             //E_DeviceFull
	"The device is not ready for r/w operations",                    //E_DeviceNotReady
	"The device is not ready for r/w operations",                    //E_NotInitialized
	"The device is already initialized",                             //E_AlreadyInitialized
	"No data can be obtained from the device",                       //E_NoDataAvailable
	"The file/data read has a wrong version number",                 //E_WrongVersion
	"Not enough memory to complete the operation",                   //E_OutOfMemory
	"Operation timed out",                                           //E_TimeOut
	"Input error occurred (typically read operation that failed)",   //E_InputError
	"Output error occurred (typically write operation that failed)", //E_OutputError
	"The device/or communication object ran out of internal MBufs",  //E_OutOfMBufs
	"The communication object ran out of request placeholder",       //E_OutOfRequests
	"Operation has aborted (often use in asynch module)",            //E_OperationAborted
	"Shared resource error (mainly file sharing)",                   //E_SharingViolation
	"Provided buffer is too small to complete operation",            //E_BufferTooSmall
	"Unknown error",                                                 //E_Unknown
	};
	return (err>=E_Err_Max||err<0) ? "Unknown error" : s_ErrorDescription[err];
}


void SetError( int err ) { 
	g_LastError = err;
	Trace( "%s\n", GetErrDescription(err) );
}

int GetError( ) {
	int temp =  g_LastError;
	g_LastError = E_Ok;
	return temp;
}

__END_NAMESPACE
